using HDLogCenter.Infrastructure.Config;
using HDLogCenter.Infrastructure.Models;
using HDLogCenter.Infrastructure.Models.Inputs;
using HDLogCenter.Infrastructure.Utils;
using Meilisearch;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

namespace HDLogCenter.Infrastructure.ExternalServices
{
    public class MeiliSearchService
    {
        private readonly MeilisearchClient _client;
        private readonly MeiliSearchConfig _config;
        private readonly ILogger<MeiliSearchService> _logger;
        private readonly HttpClient _httpClient;

        public MeiliSearchService(IOptionsMonitor<MeiliSearchConfig> configOptions, ILogger<MeiliSearchService> logger)
        {
            _config = configOptions.CurrentValue;
            _httpClient = new HttpClient();
            _httpClient.BaseAddress = new Uri(_config.Host);
            _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _config.ApiKey);
            _logger = logger;
            _client = new MeilisearchClient(_httpClient);
        }

        public async Task<SearchResult<LogDto>> SearchLogsAsync(SearchLogsInput input)
        {
            try
            {
                var index = _client.Index(_config.IndexName);
                // 构建过滤条件
                var filters = new List<string>();

                if (!string.IsNullOrEmpty(input.AppCode))
                    filters.Add($"appCode = \"{input.AppCode}\"");
                if (input.Level > 0)
                    filters.Add($"level = {input.Level}");

                if (input.StartTime.HasValue)
                    filters.Add($"createTime >= {input.StartTime.Value.ToUnixTime()}"); // 默认秒级
                if (input.EndTime.HasValue)
                    filters.Add($"createTime <= {input.EndTime.Value.ToUnixTime()}");   // 默认秒级


                var filterStr = filters.Any() ? string.Join(" AND ", filters) : null;

                var sort = new List<string> { "createTime:desc" };

                var searchQuery = new SearchQuery
                {
                    Filter = filterStr,
                    Limit = input.PageSize,
                    Offset = (input.PageIndex - 1) * input.PageSize,
                    Sort = sort
                };

                var result = await index.Search<LogDto>(input.Message ?? "", searchQuery);
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "MeiliSearch 搜索失败");
                return new SearchResult<LogDto>
                {
                    Hits = new List<LogDto>(),
                    Limit = input.PageSize,
                    Offset = (input.PageIndex - 1) * input.PageSize,
                    NbHits = 0
                };
            }
        }


        public async Task<int> GetLogsCountAsync(SearchLogsInput input)
        {
            var index = _client.Index(_config.IndexName);
            var filters = new List<string>();
            if (input.StartTime.HasValue)
                filters.Add($"Timestamp >= {((DateTimeOffset)input.StartTime.Value).ToUnixTimeSeconds()}");
            if (input.EndTime.HasValue)
                filters.Add($"Timestamp <= {((DateTimeOffset)input.EndTime.Value).ToUnixTimeSeconds()}");
            var searchQuery = new SearchQuery
            {
                Filter = filters
            };
            var result = await index.Search<LogDto>("", searchQuery);
            return result.NbHits; // 就是符合条件的数量
        }

        public async Task<LogDto> GetLogByIdAsync(string id)
        {
            try
            {
                var index = _client.Index(_config.IndexName);
                var document = await index.GetDocument<LogDto>(id);
                return document;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "MeiliSearch 获取文档失败: {Id}", id);
                return null;
            }
        }

        public async Task<bool> BatchInsertLogsAsync(IEnumerable<LogDto> logs)
        {
            try
            {
                var index = _client.Index(_config.IndexName);
                var updateStatus = await index.AddDocuments(logs);
                return true;
            }
            catch (Exception ex)
            {
                _logger.LogError($"MeiliSearch 批量添加文档失败,Msg:{ex.Message} logs:{JsonConvert.SerializeObject(logs)}", ex);
                return false;
            }
        }
        //public async Task<bool> DeleteLogAsync(string id)
        //{
        //    try
        //    {
        //        var index = _client.Index(_config.IndexName);
        //        var task = await index.DeleteOneDocumentAsync(id);
        //        await index.WaitForTaskAsync(task.TaskUid);
        //        return true;
        //    }
        //    catch (Exception ex)
        //    {
        //        _logger.LogError(ex, "MeiliSearch 删除文档失败: {Id}", id);
        //        return false;
        //    }
        //}





        //public async Task<IEnumerable<string>> GetServerCodesAsync()
        //{
        //    try
        //    {
        //        var index = _client.Index(_config.IndexName);
        //        // 使用搜索来获取所有唯一的 serverCode 值
        //        var searchResult = await index.SearchAsync<LogDto>("", new SearchQuery
        //        {
        //            AttributesToRetrieve = new[] { "server_code" },
        //            Limit = 1000
        //        });

        //        if (searchResult is Meilisearch.SearchResult<LogDto> result)
        //        {
        //            return result.Hits?
        //                .Select(h => h.ServerCode)
        //                .Where(s => !string.IsNullOrEmpty(s))
        //                .Distinct()
        //                .OrderBy(s => s)
        //                .ToList() ?? new List<string>();
        //        }
        //        return new List<string>();
        //    }
        //    catch (Exception ex)
        //    {
        //        _logger.LogError(ex, "MeiliSearch 获取服务器代码失败");
        //        return new List<string>();
        //    }
        //}

        //public async Task<IEnumerable<string>> GetAppCodesAsync()
        //{
        //    try
        //    {
        //        var index = _client.Index(_config.IndexName);
        //        // 使用搜索来获取所有唯一的 code 值
        //        var searchResult = await index.SearchAsync<LogDto>("", new SearchQuery
        //        {
        //            AttributesToRetrieve = new[] { "code" },
        //            Limit = 1000
        //        });

        //        if (searchResult is Meilisearch.SearchResult<LogDto> result)
        //        {
        //            return result.Hits?
        //                .Select(h => h.Code)
        //                .Where(s => !string.IsNullOrEmpty(s))
        //                .Distinct()
        //                .OrderBy(s => s)
        //                .ToList() ?? new List<string>();
        //        }
        //        return new List<string>();
        //    }
        //    catch (Exception ex)
        //    {
        //        _logger.LogError(ex, "MeiliSearch 获取应用代码失败");
        //        return new List<string>();
        //    }
        //}

        //public async Task<bool> InitializeIndexAsync()
        //{
        //    try
        //    {
        //        var index = _client.Index(_config.IndexName);

        //        // 设置可搜索属性
        //        await index.UpdateSearchableAttributesAsync(new[] { "message", "server_code", "code", "server_ip", "url" });

        //        // 设置可过滤属性
        //        await index.UpdateFilterableAttributesAsync(new[] { "server_code", "code", "level", "create_time", "is_timeout" });

        //        // 设置可排序属性
        //        await index.UpdateSortableAttributesAsync(new[] { "create_time", "level", "millisecond" });

        //        // 设置显示属性
        //        await index.UpdateDisplayedAttributesAsync(new[] { "*" });

        //        _logger.LogInformation("MeiliSearch 索引初始化完成");
        //        return true;
        //    }
        //    catch (Exception ex)
        //    {
        //        _logger.LogError(ex, "MeiliSearch 索引初始化失败");
        //        return false;
        //    }
        //}
    }
}
